Quick sort and Hoar sortΒΆ

Performance:
Time: from O(N*logN) to O(N^2)
def quick_sort(A):
    if len(A) < 2:
        return A

    pivot = A[0]                                        # or randomly selected item

    # []
    less    = [x for x in A[1:] if x <= pivot]          # left subarray of all items <= pivot
    # [23, 12, 9, 30, 2, 50]
    greater = [x for x in A[1:] if x > pivot]           # right subarray of all items > pivot
    # [] + [1] + [[12, 9, 2] + [23] + [30, 50]]
    # [] + [1] + [[[9,2] + [12] + []] + [23] + [[] + [30] + [50]]]
    # [] + [1] + [[[[2] + [9] + []] + [12] + []] + [23] + [[] + [30] + [50]]]
    return quick_sort(less) + [pivot] + quick_sort(greater)

def hoar_sort(A):
    if len(A) <= 1:
        return

    pivot = A[0]                                        # or randomly selected item

    L = []; M = []; R = []                              # extra memory = len(A)
    for x in A:                                         # without slices here
        if x < pivot:
            L.append(x)                                 # [5, 9, 2]
        elif x == pivot:
           M.append(x)                                  # [12]
        else:
            R.append(x)                                 # [23, 30, 50]
    hoar_sort(L)
    hoar_sort(R)
    k = 0
    for x in L + M + R:
       A[k] = x
       k += 1

Test:

def test_quick_sort(sort_algorithm):
    print("Testing: ", sort_algorithm.__doc__)
    print("testcase #1: ", end="")
    A = [12, 2, 5, 9, 30, 2, 50]
    A_sorted = [2, 2, 5, 9, 12, 30, 50]
    # returning in new array
    Res = sort_algorithm(A)
    print("Ok" if Res == A_sorted else "Fail")

def test_hoar_sort(sort_algorithm):
    print("Testing: ", sort_algorithm.__doc__)
    print("testcase #2: ", end="")
    A = [12, 23, 5, 12, 30, 2, 50]
    A_sorted = [2, 5, 12, 12, 23, 30, 50]
    # returning in the same array
    hoar_sort(A)
    print("Ok" if A == A_sorted else "Fail")

if __name__ == "__main__":
    test_quick_sort(quick_sort)
    test_hoar_sort(hoar_sort)